#include "PCSClient.h"
#include <QDebug>
#include <IceGrid/IceGrid.h>
#include <QDateTime>
#include "src/confdeal.h"

PCSClient::PCSClient(QObject * parent)
    : QThread(parent), m_bConnect(false),m_activate(false)
{
    ConfDeal *ptr_ConfDeal = ConfDeal::getInstance();
    runType = ptr_ConfDeal->getIceRunType();
    if(this->connect())
    {
        m_activate = true;
    }
};

PCSClient::~PCSClient()
{
	disconnect();
};

void PCSClient::run()
{
    while (true) {
        if(m_activate)
        {
            m_activate = false;
            //wait 30s
            this->sleep(30);
        }
        if(!m_activate){
            disconnect();
            if(connect())
            {
                m_activate = true;
            }
        }
        this->msleep(100);
    }
    exec();
}

Ice::CommunicatorPtr PCSClient::communicator()
{
    fprintf(stderr, "PCSClient::communicator()\n");
	if(m_ic == NULL){
		char ** argv;
		char *p = NULL;
		argv = &p;
		int argc = 0;
		Ice::InitializationData initData;
		initData.properties = Ice::createProperties();
        std::string  confFile=runType>0?"config1.client":"config0.client";
        qInfo()<<QString("load %1 start").arg(confFile.c_str());
        initData.properties->load(confFile);
        qInfo()<<QString("load %1 finish").arg(confFile.c_str());
		m_ic = Ice::initialize(argc, argv,initData);
	}
	return m_ic;
};

bool PCSClient::connect()
{
    if(!m_bConnect)
    {
        try{
            qInfo()<<"ServerAchievePrx::checkedCast";
            if(runType>0){
                soneway = ServerAchievePrx::checkedCast(
                    communicator()->propertyToProxy("SyePcs.Proxy")->ice_twoway()->ice_secure(true));
            }else{
                try
                {
                    qInfo()<<"checkedCast pcsio";
                    soneway = ServerAchievePrx::checkedCast(
                                communicator()->stringToProxy("PCSIO")->ice_twoway()->ice_secure(false));
                }
                catch(const Ice::NotRegisteredException&)
                {
                    qInfo()<<"checkedCast MCSSVCGrid/Query";
                    IceGrid::QueryPrx query = IceGrid::QueryPrx::checkedCast(communicator()->stringToProxy("MCSSVCGrid/Query"));
                    soneway = ServerAchievePrx::checkedCast(
                                query->findObjectByType("::PCS::PCSIO")->ice_twoway()->ice_secure(false));
                }
            }
            if(!soneway)
            {
                std::cerr <<"couldn't find a `SyePcs.Proxy' object." << std::endl;
            }else{
                std::cerr <<"find a `SyePcs.Proxy' object." << std::endl;
                //ServerAchievePrx oneway = twoway->ice_oneway();
                //ServerAchievePrx batchOneway = twoway->ice_batchOneway();
                //ServerAchievePrx datagram = twoway->ice_datagram();
                //ServerAchievePrx batchDatagram = twoway->ice_batchDatagram();
                Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("");
                Ice::Identity ident;
                ident.name = IceUtil::generateUUID();
                m_strUUID = ident.name;
                ident.category = "";
				ClientAchievePtr crtwoway = new ClientAchieveI(this);
                adapter->add(crtwoway, ident);
				adapter->activate();
                soneway->ice_getConnection()->setAdapter(adapter);
                soneway->AddClient(ident);
				m_bConnect = true;
            }
        }catch(const Ice::Exception& ex)
        {
            fprintf(stderr, "%s\n", ex.ice_name().c_str());
        }catch (const std::string & msg) {
            fprintf(stderr, "%s\n", msg.c_str());
        } catch (const char * msg) {
            fprintf(stderr, "%s\n", msg);
        }
    }
	return m_bConnect;
};

void PCSClient::disconnect()
{
	if(m_ic)
	{
		try
		{
			m_ic->destroy();
			m_ic=NULL;
		}
		catch(const Ice::Exception& ex)
		{
			fprintf(stderr, "%s\n", ex.ice_name().c_str());
		}
	}
	if(m_bConnect){
		m_bConnect=false;
	}
};

void PCSClient::addDev(const ::PCS::Devs &devs)
{
    m_activate = true;
    for(::PCS::Devs::const_iterator it=devs.begin();it!=devs.end(); it++)
    {
        emit addDev_signal(it->devID,it->devType
                    ,QString("%1").arg(it->name.c_str())
                    ,QString("%1").arg(it->desc.c_str()));
//        std::cerr<< it->devID<<","<<it->devType<<","<<it->name<<","<<it->desc<<std::endl;
    }
}

void PCSClient::addPInfo(::Ice::Long devID, const ::PCS::PInfos &pinfos)
{
    m_activate = true;
//    std::cerr<<"devID:"<<devID<<std::endl;
    for(::PCS::PInfos::const_iterator it = pinfos.begin(); it!=pinfos.end(); it++)
    {
        emit addPInfo_signal(devID,it->pID
                      ,QString("%1").arg(it->name.c_str())
                      ,QString("%1").arg(it->desc.c_str())
                      ,it->pType,QString("%1").arg(it->pValue, 0, 'f', 3));
//        std::cerr<< it->pID<<","<<it->name<<","<<it->desc<<","<<it->pType<<","<<it->pValue<<std::endl;
    }
}

void PCSClient::PValueChange(::Ice::Long devID
                              ,::Ice::Long pID
                              , const ::PCS::DateTimeI& itime
                              , ::Ice::Float val)
{
    m_activate = true;
    if(devID<0&&pID<0){
        //心跳信息
        return;
    }
    QString dt_str = QDateTime::fromTime_t(itime.isec).addMSecs(itime.imsec).toString("MM-dd hh:mm:ss.zzz");
    emit PValue_signal(devID,pID,dt_str,QString("%1").arg(val, 0, 'f', 3));
    //std::cerr <<" PValueChange:" <<devID<<","<<pID<<","<<val<<","<<itime.isec<<","<<itime.imsec<< std::endl;
};

void PCSClient::setPValue(int devID,int pID,qreal val)
{
    std::cerr << "sendTest" << std::endl;
    if(connect())
    {
        try{
            soneway->setPValue(devID,pID,val);
        }catch(...)
        {
            disconnect();
        }
    }
}
